package br.com.gsc.vaadin;

import java.lang.reflect.Constructor;
import java.util.logging.Logger;

import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;

import br.com.gsc.model.tableMapping.Admin;
import br.com.gsc.model.tableMapping.Person;
import br.com.gsc.repository.objRepos.PersonRepository;
import br.com.gsc.setup.AuthenticationHolder;

import com.vaadin.Application;
import com.vaadin.terminal.Sizeable;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.MenuBar;
import com.vaadin.ui.MenuBar.Command;
import com.vaadin.ui.MenuBar.MenuItem;
import com.vaadin.ui.Panel;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

@org.springframework.stereotype.Component
@Configurable(preConstruction=true, autowire=Autowire.BY_TYPE)
public class VaadinAdminServlet extends Application {

	/**
	 * 
	 */
	private static final long serialVersionUID = -1481084776783567319L;
	private Window window;
	private VerticalLayout vertLayout;
	private MenuBar menu;
	private Panel centralPanel;
	private Button btnCadastraEmpresa;
	private static final Logger logger = Logger.getLogger(VaadinAdminServlet.class.getName());
	@Autowired
	private PersonRepository pRepo;
	@Autowired
	private AuthenticationHolder auth;
	private Button btnCadastraProduto;
	private Button btnCadastraUsuario;
	private Button btnGraph;
	private TotalTopicPerProductWindow totalTopicsPerProductChart;
	private TypesOfTopicsPerProduct typeOfTopicCharts;
	private OperatorAnswersChart operatorChartWindow;
	private Button btnGraph2;
	private Button btnGraph3;
	private ComponentContainer secondHorzRow;
	
	   // The default application's inner window width using CSS style
	   public static final String DEFAULT_INNER_WINDOW_WIDTH = "600px";
	   // The default application's inner window height using CSS style
	   public static final String DEFAULT_INNER_WINDOW_HEIGHT = "600px";
	   // The default distance of Window left border in pixels from left border of the containing (main window).
	   public static final int DEFAULT_INNER_WINDOW_LEFT_BORDER = 30;
	   // The default distance of Window top border in pixels from left border of the containing (main window).
	   public static final int DEFAULT_INNER_WINDOW_TOP_BORDER = 30;
	   public static final int DEFAULT_WINDOW_BUTTON_WIDTH = 200;		  
	   
	   
	public void init() {
		createWindow();
	}
	
	public void createWindow(){	
		this.setTheme("mytheme");
		window = new Window();			
		createComponents();
		setMainWindow(window);
		window.getContent().setSizeFull();	
	}
	
	   /**
	    * Metodo que cria os componentes visuais. Chama o metodo para criar o painel central.
	    */
	   public void createComponents()
	   {
	      vertLayout = new VerticalLayout();
	      vertLayout.setMargin(false, true, false, true);
	      vertLayout.setSpacing(true);
	      vertLayout.addComponent(menuCreator());
	      vertLayout.addComponent(centralPanelCreator());
	      vertLayout.setComponentAlignment(centralPanel, Alignment.MIDDLE_CENTER);
	      vertLayout.setExpandRatio(centralPanel, 1.0f);
	      vertLayout.setSizeFull();
	      window.setContent(vertLayout);
	   }
	   
	   private Component centralPanelCreator()
	   {
	      centralPanel = new Panel("Controles");
//	      centralPanel.setHeight(600, Sizeable.UNITS_PIXELS);
	      centralPanel.setHeight(100, Sizeable.UNITS_PERCENTAGE);
	      centralPanel.setWidth(100, Sizeable.UNITS_PERCENTAGE);
	      centralPanel.getContent().setSizeFull();
	      HorizontalLayout firstHorzRow = new HorizontalLayout();
	      HorizontalLayout secondHorzRow = new HorizontalLayout();
	      firstHorzRow.setSpacing(true);
	      firstHorzRow.setMargin(true);
	      firstHorzRow.setHeight("300px");
	      firstHorzRow.setWidth("100%");
	      secondHorzRow.setSpacing(true);
	      secondHorzRow.setMargin(true);
	      secondHorzRow.setHeight("300px");
	      secondHorzRow.setWidth("100%");
	      
	      
//	      estilo para customizar os botoes
//	      btnCadastraEmpresa.addStyleName("stl_button");
//	      btnCadastraProduto.addStyleName("stl_button");
	    
	      Person p = pRepo.findPersonByID(auth.getAuthentication().getName());
	      if(p instanceof Admin && ((Admin)p).isSuperAdmin()){
			// Botao de SAs com problema	  
			btnCadastraEmpresa = new DefaultMainWindowButtonComponent(
					"Cadastrar Empresas", "img/add_company.png", AddCompanyWindow.class);
		      firstHorzRow.addComponent(btnCadastraEmpresa);
		      firstHorzRow.setComponentAlignment(btnCadastraEmpresa, Alignment.MIDDLE_CENTER);
	      }
	      
			btnCadastraProduto = new DefaultMainWindowButtonComponent(
					"Cadastrar Produtos", "img/add_product.png", AddProductWindow.class);
		      firstHorzRow.addComponent(btnCadastraProduto);
		      firstHorzRow.setComponentAlignment(btnCadastraProduto, Alignment.MIDDLE_CENTER);
	      
		    btnCadastraUsuario = new DefaultMainWindowButtonComponent(
						"Cadastrar Usuarios", "img/add_user.png", AddPowerUser.class);
			      firstHorzRow.addComponent(btnCadastraUsuario);
			      firstHorzRow.setComponentAlignment(btnCadastraUsuario, Alignment.MIDDLE_CENTER);
		      
	      btnGraph = new Button("Topico x produto");
	      btnGraph.addStyleName("icon-on-top stl_button");
	      btnGraph.setWidth(DEFAULT_WINDOW_BUTTON_WIDTH, Sizeable.UNITS_PIXELS);
	      btnGraph.setIcon(new ThemeResource("img/chart.png"));
	      secondHorzRow.addComponent(btnGraph);
	      secondHorzRow.setComponentAlignment(btnGraph, Alignment.MIDDLE_CENTER);
	      btnGraph.addListener(new Button.ClickListener()
	      {
	         /**
			 * 
			 */
			private static final long serialVersionUID = 1L;

			public void buttonClick(ClickEvent event)
	         {
	            try
	            {
	               totalTopicsPerProductChart = new TotalTopicPerProductWindow();
	               totalTopicsPerProductChart.setApplication(null);
	               totalTopicsPerProductChart.setPositionX(DEFAULT_INNER_WINDOW_LEFT_BORDER);
	               totalTopicsPerProductChart.setPositionY(DEFAULT_INNER_WINDOW_TOP_BORDER);
	               totalTopicsPerProductChart.setVisible(true);	               
	               getMainWindow().addWindow(totalTopicsPerProductChart);
	            } catch (Exception e){
	               // TODO Auto-generated catch block
	               e.printStackTrace();
	            }
	         }
	      });
	      
	      btnGraph2 = new Button("Tipos de topicos x prod.");
	      btnGraph2.addStyleName("icon-on-top stl_button");	      
	      btnGraph2.setWidth(DEFAULT_WINDOW_BUTTON_WIDTH, Sizeable.UNITS_PIXELS);
	      btnGraph2.setIcon(new ThemeResource("img/chart.png"));
	      secondHorzRow.addComponent(btnGraph2);
	      secondHorzRow.setComponentAlignment(btnGraph2, Alignment.MIDDLE_CENTER);
	      btnGraph2.addListener(new Button.ClickListener()
	      {
	         /**
			 * 
			 */
			private static final long serialVersionUID = 1L;			

			public void buttonClick(ClickEvent event)
	         {
	            try
	            {
	               typeOfTopicCharts = new TypesOfTopicsPerProduct();
	               typeOfTopicCharts.setApplication(null);
	               typeOfTopicCharts.setPositionX(DEFAULT_INNER_WINDOW_LEFT_BORDER);
	               typeOfTopicCharts.setPositionY(DEFAULT_INNER_WINDOW_TOP_BORDER);
	               typeOfTopicCharts.setVisible(true);	               
	               getMainWindow().addWindow(typeOfTopicCharts);
	            } catch (Exception e){
	               // TODO Auto-generated catch block
	               e.printStackTrace();
	            }
	         }
	      });
	      
	      btnGraph3 = new Button("Topicos por operador");
	      btnGraph3.addStyleName("icon-on-top stl_button");	      
	      btnGraph3.setWidth(DEFAULT_WINDOW_BUTTON_WIDTH, Sizeable.UNITS_PIXELS);
	      btnGraph3.setIcon(new ThemeResource("img/chart.png"));
	      secondHorzRow.addComponent(btnGraph3);
	      secondHorzRow.setComponentAlignment(btnGraph3, Alignment.MIDDLE_CENTER);
	      btnGraph3.addListener(new Button.ClickListener()
	      {
	         /**
			 * 
			 */
			private static final long serialVersionUID = 1L;			

			public void buttonClick(ClickEvent event)
	         {
	            try
	            {
	            	operatorChartWindow = new OperatorAnswersChart();
	            	operatorChartWindow.setApplication(null);
	            	operatorChartWindow.setPositionX(DEFAULT_INNER_WINDOW_LEFT_BORDER);
	            	operatorChartWindow.setPositionY(DEFAULT_INNER_WINDOW_TOP_BORDER);
	            	operatorChartWindow.setVisible(true);	               
	            	getMainWindow().addWindow(operatorChartWindow);
	            } catch (Exception e){
	               // TODO Auto-generated catch block
	               e.printStackTrace();
	            }
	         }
	      });
		      
	      centralPanel.addComponent(firstHorzRow);
	      centralPanel.addComponent(secondHorzRow);
	      return centralPanel;	    
	   }
	   
	   private Component menuCreator()
	   {
	      menu = new MenuBar();
	      menu.setWidth(100, Sizeable.UNITS_PERCENTAGE);
	      MenuItem arquivos = menu.addItem("Arquivos", null);
	      arquivos.addItem("Abrir", null);
	      arquivos.addItem("Salvar", null);
	      arquivos.setEnabled(false);
	      MenuItem reposts = menu.addItem("Reports", null);
	      reposts.addItem("Teste 1", menuCommand);
	      reposts.setEnabled(false);
	      MenuItem graficos = menu.addItem("Graficos", null);
	      graficos.setEnabled(false);
	      return menu;
	   }
	   
	   private Command menuCommand = new Command()
	   {
		private static final long serialVersionUID = -5401829687662729364L;

	      public void menuSelected(MenuItem selectedItem)
	      {
//	         getMainWindow().addWindow(hh);
//	         hh.setPositionX(25);
//	         hh.setPositionY(25);
//	         hh.setVisible(true);
	      }
	   };
	   
	   
	   
	   /**
	    * Inner class that concentrates the new Window initializations. This will help on standardization of the application.
	    * Depending on the component that is being created, it may throw many kind of exceptions, therefore this class throws Exception itself. It is up tp the called knowing which kind of Exception it should be captured. 
	    */
	   class DefaultMainWindowButtonComponent extends Button
	   {		  
	      private static final long serialVersionUID = 1L;
	      private static final String STYLENAME = "icon-on-top";
	      public DefaultMainWindowButtonComponent(final String buttonTitle, String buttonIcon, final Class<? extends CustomComponent> clazz, final Object... parameters)
	      {
	         super(buttonTitle);
	         logger.info(buttonTitle+" created.");
	         addStyleName(STYLENAME);
	         addStyleName("stl_button");
	         setWidth(DEFAULT_WINDOW_BUTTON_WIDTH, Sizeable.UNITS_PIXELS);
	         setIcon(new ThemeResource(buttonIcon));
	         addListener(new Button.ClickListener()
	         {
	            private static final long serialVersionUID = 1L;

	            public void buttonClick(ClickEvent event)
	            {
	               logger.info("Button " + event.getButton().getCaption() + " clicked.");
	               DefaultWindowComponent windowComponentToShow;
	               ComponentContainer comp;
	               try
	               {
	            	   if(parameters.length > 0)
	            	   {
	            		   Class<?>[] classArr = new Class[parameters.length];
	            		   int counter = 1;
	            		   do
	            		   {
	            			   classArr[counter] = parameters[counter].getClass();
	            		   }while(counter < parameters.length);
	            		   Constructor<? extends ComponentContainer> cons = clazz.getConstructor(classArr);
	            		   comp = cons.newInstance(parameters);
	                  }else{	            		   
	            			comp = clazz.newInstance();
	            		   
	                  }
	                  
	                  windowComponentToShow = new DefaultWindowComponent(buttonTitle, comp);
	                  logger.fine(windowComponentToShow.getCaption()+" will be called.");
	                  getMainWindow().removeWindow(windowComponentToShow);
	                  getMainWindow().addWindow(windowComponentToShow);
	               } catch (Exception e)
	               {
//	                  logger.severe("It was not possible to open window");
//	                  logger.severe(e.getMessage());
	                  e.printStackTrace();
//	                  getWindow().showNotification("Erro",
//	                		  "Não foi possível abrir a janela. Para mais informaçõees, verifique o log.",
//	                          Notification.TYPE_ERROR_MESSAGE);
	               }
	            }
	         });
	      }
	   }
	   
	   /**
	    * Inner class that concentrates the new Window initializations. This will help on standardization of the application.
	    */
	   class DefaultWindowComponent extends Window
	   {
	      private static final long serialVersionUID = 1L;
	      public DefaultWindowComponent(String title, ComponentContainer innerComponent)
	      {
	         super(title, innerComponent);
	         if(innerComponent instanceof AddPowerUser){
	        	 setWidth("800px");
		         setHeight("525px");
	         }else{
	        	setWidth(DEFAULT_INNER_WINDOW_WIDTH);
	         	setHeight(DEFAULT_INNER_WINDOW_HEIGHT);
	         }
	         setPositionX(DEFAULT_INNER_WINDOW_LEFT_BORDER);
	         setPositionY(DEFAULT_INNER_WINDOW_TOP_BORDER);
	         logger.fine("Window "+title+ " created.");
	      }      
	   }
}